package com.zhejiangzhengyuan.municipal_common.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhejiangzhengyuan.municipal_common.entity.File;
import com.zhejiangzhengyuan.municipal_common.entity.Problems;
import com.zhejiangzhengyuan.municipal_common.entity.ProblemsFileMapping;
import com.zhejiangzhengyuan.municipal_common.entity.vo.ProblemsVo;
import com.zhejiangzhengyuan.municipal_common.mapper.ProblemsMapper;
import com.zhejiangzhengyuan.municipal_common.response.ResponseVo;
import com.zhejiangzhengyuan.municipal_common.service.FileService;
import com.zhejiangzhengyuan.municipal_common.service.ProblemsFileMappingService;
import com.zhejiangzhengyuan.municipal_common.service.ProblemsService;
import com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil.timeFormat;
import static com.zhejiangzhengyuan.municipal_common.utils.excelFileUtils.FileUtil.getUrlsByRequest;

/**
 * 服务实现类
 *
 * @author linju
 * @since 2019-12-12
 */
@Service
public class ProblemsServiceImpl extends ServiceImpl<ProblemsMapper, Problems>
    implements ProblemsService {
  @Autowired private FileService fileService;
  @Autowired private ProblemsMapper problemsMapper;
  @Autowired private ProblemsFileMappingService problemsFileMappingService;

  @Override
  public ResponseVo saveProblems(Problems problems) {
    // location 为 longitude,latitude 预存待转换
    String location = problems.getGeometry();
    problems.setGeometry(null);
    Timestamp time = timeFormat(System.currentTimeMillis());
    // 若插入值小于0 表示插入失败
    if (problemsMapper.insert(problems.setCreateTime(time).setUpdateTime(time)) > 0) {
      // 若location存在则修改其geometry
      if (Strings.isNotBlank(location)) {
        String[] geometry = location.split(",");
        problemsMapper.updateGeometry(problems.getId(), geometry[0], geometry[1]);
      }
      return ResponseVo.successWithData(problems);
    }
    return ResponseVo.SERVER_ERROR;
  }

  @Override
  public ResponseVo getVoById(Long id) {
    ProblemsVo problemsVo = problemsMapper.getVoById(id);
    if(Objects.isNull(problemsVo)){
      return ResponseVo.NOT_FOUND_RESOURCES;
    }
    formatProblemsVo(problemsVo);
    return ResponseVo.successWithData(problemsVo);
  }

  @Override
  public ResponseVo insertProblemsFile(
      Long problemsId, MultipartFile beforeFile, MultipartFile afterFile) {
    // 上传文件
    if (Objects.isNull(problemsMapper.selectById(problemsId))) {
      return ResponseVo.CLIENT_PARAM_ERROR;
    }
    String moduleName = "municipal_sewage";
    ProblemsFileMapping problemsFileMapping = new ProblemsFileMapping();
    File beforeFilePo = null;
    File afterFilePo = null;
    try {
      beforeFilePo =
          Objects.isNull(beforeFile) || beforeFile.isEmpty()
              ? null
              : fileService.saveFile(moduleName, beforeFile);
      afterFilePo =
          Objects.isNull(afterFile) || afterFile.isEmpty()
              ? null
              : fileService.saveFile(moduleName, afterFile);
    } catch (IOException e) {
      return ResponseVo.errorWithException(e);
    }
    // 关联主键
    if (Objects.nonNull(beforeFilePo)) {
      problemsFileMapping
          .setFileId(beforeFilePo.getId())
          .setProblemsId(problemsId)
          .setRectify("before")
          .setCreateTime(timeFormat(System.currentTimeMillis()))
          .setUpdateTime(timeFormat(System.currentTimeMillis()));
      problemsFileMappingService.save(problemsFileMapping);
      return ResponseVo.SUCCESS;
    }
    if (Objects.nonNull(afterFilePo)) {
      problemsFileMapping
          .setFileId(afterFilePo.getId())
          .setProblemsId(problemsId)
          .setRectify("after")
          .setCreateTime(timeFormat(System.currentTimeMillis()))
          .setUpdateTime(timeFormat(System.currentTimeMillis()));
      problemsFileMappingService.save(problemsFileMapping);
      return ResponseVo.SUCCESS;
    }
    return ResponseVo.SUCCESS;
  }

  @Override
  public ResponseVo removeProblemsByIds(List<Long> ids) {
    // 删除problems 和文件
    Collection<Problems> problems = this.listByIds(ids);
    if (Objects.isNull(problems) || problems.isEmpty()) {
      // 找不到对应id的problems
      return ResponseVo.CLIENT_PARAM_ERROR;
    }
    // 删除文件
    QueryWrapper<ProblemsFileMapping> queryWrapper = new QueryWrapper<>();
    queryWrapper.in("problems_id", ids);
    List<ProblemsFileMapping> problemsFileMappings = problemsFileMappingService.list(queryWrapper);
    for (ProblemsFileMapping problemsFileMapping : problemsFileMappings) {
      try {
        fileService.removeFileById(problemsFileMapping.getFileId());
      } catch (IOException e) {
        return ResponseVo.errorWithException(e);
      }
    }
    // 删除problems
    this.removeByIds(ids);
    return ResponseVo.SUCCESS;
  }

  @Override
  public ResponseVo updateProblems(Problems problems, String linkList) {
    String[] split = getUrlsByRequest(linkList);
    if (split != null && split.length > 0) {
      // 删除文件
      for (String s : split) {
        QueryWrapper<File> fileQueryWrapper = new QueryWrapper<>();
        fileQueryWrapper.eq("link", s);
        File file = fileService.getOne(fileQueryWrapper);
        if (file != null) {
          QueryWrapper<ProblemsFileMapping> fileMappingQueryWrapper = new QueryWrapper<>();
          fileMappingQueryWrapper.eq("file_id", file.getId());
          if (problemsFileMappingService.remove(fileMappingQueryWrapper)) {
            try {
              fileService.removeFileById(file.getId());
            } catch (IOException e) {
              return ResponseVo.errorWithException(e);
            }
          }
        }
      }
    }
    String location = problems.getGeometry();
    problems.setGeometry(null);
    // before和after不为null则需要将之前文件删除
    Timestamp time = timeFormat(System.currentTimeMillis());
    // 若插入值小于0 表示插入失败
    if (problemsMapper.updateById(problems.setUpdateTime(time)) > 0) {
      // 若location存在则修改其geometry
      if (Strings.isNotBlank(location)) {
        String[] geometry = location.split(",");
        problemsMapper.updateGeometry(problems.getId(), geometry[0], geometry[1]);
      }
      return ResponseVo.successWithData(problems);
    }
    return ResponseVo.SERVER_ERROR;
  }

  @Override
  public ResponseVo removeProblems(Long problemsId) {
    // 删除problems 和文件
    Problems problems = this.getById(problemsId);
    if (Objects.isNull(problems)) {
      // 找不到对应id的problems
      return ResponseVo.CLIENT_PARAM_ERROR;
    }
    // 删除文件
    QueryWrapper<ProblemsFileMapping> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("problems_id", problemsId);
    List<ProblemsFileMapping> problemsFileMappings = problemsFileMappingService.list(queryWrapper);
    for (ProblemsFileMapping problemsFileMapping : problemsFileMappings) {
      try {
        fileService.removeFileById(problemsFileMapping.getFileId());
      } catch (IOException e) {
        return ResponseVo.errorWithException(e);
      }
    }
    // 删除problems
    this.removeById(problemsId);
    return ResponseVo.SUCCESS;
  }

  @Override
  public Page<ProblemsVo> selectVoPage(
      Page<ProblemsVo> voPage,
      String area,
      String projectNum,
      String defectItemCode,
      String problemsCode,
      String startTimestamp,
      String endTimestamp) {
    Page<ProblemsVo> problemsVoPage = problemsMapper.selectVoPage(
            voPage, area, projectNum, defectItemCode, problemsCode, startTimestamp, endTimestamp);
    //封装文件路径
    for (ProblemsVo vo:problemsVoPage.getRecords()){
      formatProblemsVo(vo);
    }
    return problemsVoPage;
  }
  private void formatProblemsVo(ProblemsVo vo){
    QueryWrapper<ProblemsFileMapping> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("problems_id", vo.getId()).eq("rectify","after");
    List<ProblemsFileMapping> list = problemsFileMappingService.list(queryWrapper);
    if(Objects.nonNull(list)&&!list.isEmpty()){
      vo.setAfterPath(fileService.getById(list.get(0).getFileId()).getLink());
    }
    queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("problems_id", vo.getId()).eq("rectify","before");
    list = problemsFileMappingService.list(queryWrapper);
    if(Objects.nonNull(list)&&!list.isEmpty()){
      vo.setBeforePath(fileService.getById(list.get(0).getFileId()).getLink());
    }
  }

  @Override
  public ResponseVo selectProblemsCharts(int month) {
    // 获取当前年份
    String year = DateFormatUtil.getStringByTime("yyyy", System.currentTimeMillis());
    // 匹配日期
    String date = year + "-" + (month < 10 ? "0" + month : month);
    JSONObject object = new JSONObject();
    object.put("all", problemsMapper.selectCountByMonth(null, date));
    // 饼状图
    JSONArray chartData = new JSONArray();
    JSONObject data = new JSONObject();
    data.put("name", "functional");
    data.put("value", problemsMapper.selectCountByMonth("功能型", date));
    chartData.add(data);
    data = new JSONObject();
    data.put("name", "structural");
    data.put("value", problemsMapper.selectCountByMonth("结构型", date));
    chartData.add(data);
    object.put("data", chartData);
    // 返回问题点图表
    return ResponseVo.successWithData(object);
  }

  @Override
  public ResponseVo selectRectifySewage(int month) {
    // 获取当前年份
    String year = DateFormatUtil.getStringByTime("yyyy", System.currentTimeMillis());
    // 匹配日期
    String date = year + "-" + (month < 10 ? "0" + month : month);
    JSONObject data = new JSONObject();
    // 功能型缺陷
    data.put("functional", formatChartsItem("功能型", date));
    // 结构型缺陷数据
    data.put("structural", formatChartsItem("结构型", date));
    // 雨污混接
    data.put("RainAndDirt", formatChartsItem("雨污混接", date));

    return ResponseVo.successWithData(data);
  }

  // 封装图表data
  private JSONArray formatChartsItem(String type, String date) {
    JSONArray dataItem = new JSONArray();
    // 整改前
    JSONObject objectItem = new JSONObject();
    objectItem.put("name", "问题数量");
    objectItem.put("value", problemsMapper.selectCountByMonth(type, date));
    dataItem.add(objectItem);
    // 整改后
    objectItem = new JSONObject();
    objectItem.put("name", "改造数量");
    objectItem.put("value", problemsMapper.selectRectifyCountByMonth(type, date));
    dataItem.add(objectItem);
    return dataItem;
  }
}
